import tkinter as tk
from tkinter import ttk, font, messagebox
from tkinter import scrolledtext
import requests
import json
import threading

class HistoryChat:
    def __init__(self, root):
        self.root = root
        self.root.title('历史对话系统')
        self.root.geometry('1200x800')
        
        # 设置窗口在屏幕中央
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        x = (screen_width - 1200) // 2
        y = (screen_height - 800) // 2
        self.root.geometry(f'1200x800+{x}+{y}')
        
        # 绑定关闭窗口事件
        self.root.protocol('WM_DELETE_WINDOW', self.on_closing)
        
        # 设置主题颜色和字体
        self.bg_color = '#F5F5DC'  # 米色背景
        self.text_color = '#2F4F4F'  # 深灰绿色文字
        self.accent_color = '#8B4513'  # 棕色强调色
        self.chinese_font = font.Font(family='Microsoft YaHei', size=10)
        
        # 配置主窗口样式
        self.root.configure(bg=self.bg_color)
        
        # 创建主框架
        self.main_frame = ttk.Frame(self.root)
        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
        
        # 创建左右分栏
        self.left_frame = ttk.Frame(self.main_frame)
        self.right_frame = ttk.Frame(self.main_frame)
        self.left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))
        self.right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(10, 0))
        
        # 创建左侧上下分栏
        self.left_top_frame = ttk.Frame(self.left_frame)
        self.left_bottom_frame = ttk.Frame(self.left_frame)
        self.left_top_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True, pady=(0, 10))
        self.left_bottom_frame.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
        
        # 创建输入区域
        self.create_input_area()
        
        # 创建历史事件列表
        self.create_history_list()
        
        # 创建显示区域
        self.create_display_area()
        
        # 应用自定义样式
        self.apply_custom_style()
        
        # 添加请求锁，防止多个请求同时执行
        self.request_lock = threading.Lock()

    def on_closing(self):
        if tk.messagebox.askokcancel('确认', '确定要退出吗？'):
            self.root.destroy()
    
    def create_input_area(self):
        # 输入区标题
        input_label = ttk.Label(
            self.left_top_frame,
            text='请输入历史事件',
            font=self.chinese_font
        )
        input_label.pack(pady=(0, 5), anchor=tk.W)
        
        # 输入文本框
        self.input_text = scrolledtext.ScrolledText(
            self.left_top_frame,
            wrap=tk.WORD,
            width=40,
            height=10,
            font=self.chinese_font,
            bg='white',
            fg=self.text_color
        )
        self.input_text.pack(fill=tk.BOTH, expand=True)
        
        # 发送按钮
        self.send_button = ttk.Button(
            self.left_top_frame,
            text='发送',
            command=self.send_message
        )
        self.send_button.pack(pady=(10, 0))
    
    def create_display_area(self):
        # 显示区标题
        display_label = ttk.Label(
            self.right_frame,
            text='历史信息',
            font=self.chinese_font
        )
        display_label.pack(pady=(0, 5), anchor=tk.W)
        
        # 显示文本框
        self.display_text = scrolledtext.ScrolledText(
            self.right_frame,
            wrap=tk.WORD,
            width=50,
            height=30,
            font=self.chinese_font,
            bg='white',
            fg=self.text_color,
            state='disabled'
        )
        self.display_text.pack(fill=tk.BOTH, expand=True)
    
    def create_history_list(self):
        # 创建左右分栏框架
        history_frame_left = ttk.Frame(self.left_bottom_frame)
        history_frame_right = ttk.Frame(self.left_bottom_frame)
        history_frame_left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5))
        history_frame_right.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(5, 0))

        # 中国历史事件列表
        china_label = ttk.Label(
            history_frame_left,
            text='中国历史重大事件',
            font=self.chinese_font
        )
        china_label.pack(pady=(0, 5), anchor=tk.W)

        # 添加中国历史事件的展开/收起按钮
        china_buttons_frame = ttk.Frame(history_frame_left)
        china_buttons_frame.pack(pady=(0, 5))
        
        china_expand_button = ttk.Button(
            china_buttons_frame,
            text='全部展开',
            command=lambda: self.expand_all(self.china_tree)
        )
        china_expand_button.pack(side=tk.LEFT, padx=5)
        
        china_collapse_button = ttk.Button(
            china_buttons_frame,
            text='全部收起',
            command=lambda: self.collapse_all(self.china_tree)
        )
        china_collapse_button.pack(side=tk.LEFT)

        self.china_tree = ttk.Treeview(
            history_frame_left,
            show='tree',
            height=15
        )

        # 中国历史时期和事件数据
        china_periods = {
            '远古时期 (-2100前)': {
                '文明起源': ['黄帝统一部落', '尧舜禹传说', '原始农业发展'],
                '青铜文明': ['青铜器制作', '甲骨文发明', '天文历法发展']
            },
            '夏商周时期 (-2100~-771)': {
                '夏朝建立 (-2070)': ['禹传启建立世袭制', '青铜冶炼技术', '天文历法发展'],
                '商朝时期 (-1600~-1046)': ['甲骨文发明', '青铜器制作', '奴隶制度完善'],
                '周朝建立 (-1046)': ['周公制礼作乐', '分封制确立', '诸侯国林立']
            },
            '春秋战国 (-770~-221)': {
                '春秋五霸': ['齐桓公尊王攘夷', '晋文公称霸', '越王勾践复国'],
                '百家争鸣': ['孔子创立儒家', '老子道家思想', '墨子兼爱非攻'],
                '变法运动': ['管仲变法', '商鞅变法', '吴起变法']
            },
            '秦汉时期 (-221~220)': {
                '秦统一': ['秦始皇统一六国', '焚书坑儒', '修建长城'],
                '西汉盛世': ['张骞通西域', '司马迁写史记', '汉武帝巡狩'],
                '东汉科技': ['张衡发明地动仪', '蔡伦改进造纸', '华佗医术']
            },
            '三国两晋南北朝 (220~581)': {
                '三国鼎立': ['曹操统一北方', '诸葛亮治蜀', '孙权据江东'],
                '西晋统一': ['司马氏夺权', '八王之乱', '永嘉之乱'],
                '南北对峙': ['北魏孝文帝改革', '南朝建康繁华', '玄学兴起']
            },
            '隋唐时期 (581~907)': {
                '隋朝统一': ['文帝创科举', '炀帝修大运河', '营建东都'],
                '贞观之治': ['玄奘西行', '李世民治国', '创立三省六部'],
                '开元盛世': ['张九龄为相', '玄宗励精图治', '边疆安定']
            },
            '宋元时期 (960~1368)': {
                '北宋科技': ['毕昇发明活字印刷', '沈括著梦溪笔谈', '苏颂制造水运仪象台'],
                '南宋抗金': ['岳飞抗金', '文天祥殉国', '抗元名将陆秀夫'],
                '元朝统一': ['忽必烈建元', '马可波罗来华', '郑和下西洋']
            },
            '明清时期 (1368~1911)': {
                '明朝建立': ['朱元璋改革', '永乐大典编纂', '郑和下西洋'],
                '清朝鼎盛': ['康熙统一台湾', '雍正改革', '乾隆十全武功'],
                '清末新政': ['洋务运动', '戊戌变法', '清末新政']
            },
            '近现代 (1911至今)': {
                '民国时期': ['辛亥革命', '五四运动', '抗日战争'],
                '新中国成立': ['开国大典', '抗美援朝', '两弹一星'],
                '改革开放': ['经济特区建立', '香港澳门回归', '载人航天工程']
            }
        }

        # 插入中国历史数据
        for period, events in china_periods.items():
            period_id = self.china_tree.insert('', tk.END, text=period)
            for event, details in events.items():
                event_id = self.china_tree.insert(period_id, tk.END, text=event)
                for detail in details:
                    self.china_tree.insert(event_id, tk.END, text=detail)

        china_scrollbar = ttk.Scrollbar(
            history_frame_left,
            orient=tk.VERTICAL,
            command=self.china_tree.yview
        )
        self.china_tree.configure(yscrollcommand=china_scrollbar.set)

        self.china_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        china_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 世界历史事件列表
        world_label = ttk.Label(
            history_frame_right,
            text='世界历史重大事件',
            font=self.chinese_font
        )
        world_label.pack(pady=(0, 5), anchor=tk.W)

        # 添加世界历史事件的展开/收起按钮
        world_buttons_frame = ttk.Frame(history_frame_right)
        world_buttons_frame.pack(pady=(0, 5))
        
        world_expand_button = ttk.Button(
            world_buttons_frame,
            text='全部展开',
            command=lambda: self.expand_all(self.world_tree)
        )
        world_expand_button.pack(side=tk.LEFT, padx=5)
        
        world_collapse_button = ttk.Button(
            world_buttons_frame,
            text='全部收起',
            command=lambda: self.collapse_all(self.world_tree)
        )
        world_collapse_button.pack(side=tk.LEFT)

        self.world_tree = ttk.Treeview(
            history_frame_right,
            show='tree',
            height=15
        )

        # 世界历史时期和事件数据
        world_periods = {
            '古代文明 (-3500~-800)': {
                '美索不达米亚文明': ['苏美尔文明', '巴比伦文明', '亚述文明'],
                '古埃及文明': ['金字塔建造', '象形文字', '法老制度'],
                '印度河流域文明': ['城市规划', '泥板文字', '宗教信仰']
            },
            '古典时期 (-800~476)': {
                '古希腊文明': ['城邦政治', '奥林匹克运动会', '苏格拉底哲学'],
                '波斯帝国': ['居鲁士大帝', '波斯帝国建立', '希波战争'],
                '罗马帝国': ['凯撒大帝', '斗兽场建造', '基督教兴起']
            },
            '中世纪 (476~1453)': {
                '拜占庭帝国': ['查士丁尼法典', '圣索菲亚大教堂', '东正教分裂'],
                '阿拉伯帝国': ['伊斯兰教创立', '阿拉伯数字', '丝绸之路繁荣'],
                '欧洲封建': ['十字军东征', '大学建立', '黑死病流行']
            },
            '文艺复兴 (1300~1600)': {
                '意大利复兴': ['但丁文学', '达芬奇艺术', '美第奇家族'],
                '地理大发现': ['哥伦布发现新大陆', '麦哲伦环球航行', '新航路开辟'],
                '宗教改革': ['马丁路德', '加尔文主义', '英国国教']
            },
            '启蒙运动 (1600~1800)': {
                '科学革命': ['伽利略', '牛顿万有引力', '显微镜发明'],
                '启蒙思想': ['伏尔泰', '卢梭社会契约论', '孟德斯鸠'],
                '工业革命': ['蒸汽机发明', '纺织业革命', '交通革命']
            },
            '近代革命 (1776~1871)': {
                '美国独立': ['独立宣言', '制宪会议', '联邦制确立'],
                '法国大革命': ['人权宣言', '拿破仑法典', '维也纳会议'],
                '民族统一': ['德意志统一', '意大利统一', '明治维新']
            },
            '两次世界大战 (1914~1945)': {
                '第一次世界大战': ['萨拉热窝事件', '凡尔登战役', '凡尔赛条约'],
                '俄国革命': ['列宁领导', '苏维埃政权', '共产国际'],
                '第二次世界大战': ['珍珠港事件', '诺曼底登陆', '原子弹爆炸']
            },
            '冷战时期 (1945~1991)': {
                '东西对峙': ['铁幕演说', '马歇尔计划', '柏林墙建立'],
                '科技竞赛': ['人类登月', '核武器竞赛', '太空竞赛'],
                '冷战结束': ['柏林墙倒塌', '苏联解体', '华沙条约解散']
            },
            '全球化时代 (1991至今)': {
                '科技革命': ['互联网普及', '智能手机革命', '人工智能发展'],
                '全球治理': ['欧盟成立', '联合国维和', '气候变化应对'],
                '世界挑战': ['恐怖主义', '金融危机', '新冠疫情']
            }
        }

        # 插入世界历史数据
        for period, events in world_periods.items():
            period_id = self.world_tree.insert('', tk.END, text=period)
            for event, details in events.items():
                event_id = self.world_tree.insert(period_id, tk.END, text=event)
                for detail in details:
                    self.world_tree.insert(event_id, tk.END, text=detail)

        world_scrollbar = ttk.Scrollbar(
            history_frame_right,
            orient=tk.VERTICAL,
            command=self.world_tree.yview
        )
        self.world_tree.configure(yscrollcommand=world_scrollbar.set)

        self.world_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        world_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 绑定双击事件
        self.china_tree.bind('<Double-1>', self.on_event_select)
        self.world_tree.bind('<Double-1>', self.on_event_select)
    
    def on_event_select(self, event):
        # 获取事件来源和选中项
        tree = event.widget
        selected_item = tree.selection()
        if selected_item:
            item = tree.item(selected_item[0])
            # 获取完整路径文本
            path_texts = []
            current_item = selected_item[0]
            while current_item:
                current_text = tree.item(current_item)['text']
                path_texts.insert(0, current_text)
                current_item = tree.parent(current_item)
            
            # 组合完整文本
            full_text = ' > '.join(path_texts)
            # 清空输入框并插入选中的事件
            self.input_text.delete('1.0', tk.END)
            self.input_text.insert('1.0', full_text)
    
    def apply_custom_style(self):
        # 创建自定义样式
        style = ttk.Style()
        style.configure(
            'TButton',
            font=self.chinese_font,
            padding=5
        )
        style.configure(
            'TLabel',
            font=self.chinese_font,
            background=self.bg_color,
            foreground=self.text_color
        )
        style.configure(
            'TFrame',
            background=self.bg_color
        )
        style.configure(
            'Treeview',
            font=self.chinese_font,
            background='white',
            fieldbackground='white',
            foreground=self.text_color
        )
        style.configure(
            'Treeview.Heading',
            font=self.chinese_font,
            background=self.bg_color
        )
    
    def send_message(self):
        # 获取输入文本
        message = self.input_text.get('1.0', tk.END).strip()
        if not message:
            return
        
        # 禁用发送按钮，显示加载状态
        self.send_button.configure(state='disabled')
        self.display_text.configure(state='normal')
        self.display_text.delete('1.0', tk.END)
        self.display_text.insert(tk.END, '正在处理请求，请稍候...', 'loading')
        self.display_text.tag_configure('loading', foreground='blue', font=self.chinese_font)
        self.display_text.configure(state='disabled')
        
        # 创建新线程处理请求
        def request_thread():
            try:
                # 获取请求锁
                with self.request_lock:
                    # 设置重试次数
                    max_retries = 3
                    retry_count = 0
                    
                    while retry_count < max_retries:
                        try:
                            # 发送请求到Flask服务器
                            response = requests.post(
                                'http://localhost:5000/chat',
                                json={'msg': message},
                                timeout=120  # 增加超时时间到120秒
                            )
                            
                            # 处理响应
                            if response.status_code == 200:
                                data = response.json()
                                # 使用after方法在主线程中更新UI
                                self.root.after(0, lambda: self.update_display(data['data']))
                                break  # 请求成功，跳出重试循环
                            else:
                                error_msg = response.json().get('message', '未知错误') if response.headers.get('content-type', '').startswith('application/json') else '服务器返回非JSON格式响应'
                                self.root.after(0, lambda: self.show_error(f'请求失败: {error_msg}'))
                                break  # 服务器返回错误，不需要重试
                        
                        except requests.exceptions.Timeout:
                            retry_count += 1
                            if retry_count < max_retries:
                                self.root.after(0, lambda: self.show_error(f'请求超时，正在进行第{retry_count + 1}次重试...'))
                                continue
                            else:
                                self.root.after(0, lambda: self.show_error('请求超时，已达到最大重试次数。请检查服务器状态或稍后重试。'))
                        
                        except requests.exceptions.RequestException as e:
                            self.root.after(0, lambda: self.show_error(f'网络请求错误: {str(e)}'))
                            break
            
            except Exception as e:
                self.root.after(0, lambda: self.show_error(f'发生错误: {str(e)}'))
            finally:
                # 恢复发送按钮状态
                self.root.after(0, lambda: self.send_button.configure(state='normal'))
        
        # 启动请求线程
        threading.Thread(target=request_thread, daemon=True).start()
    
    def update_display(self, response_data):
        # 启用文本框编辑
        self.display_text.configure(state='normal')
        
        # 清空现有内容
        self.display_text.delete('1.0', tk.END)
        
        # 配置文本样式
        self.display_text.tag_configure(
            'title',
            font=font.Font(family='Microsoft YaHei', size=12, weight='bold'),
            foreground=self.accent_color,
            spacing1=10,
            spacing3=5
        )
        self.display_text.tag_configure(
            'subtitle',
            font=font.Font(family='Microsoft YaHei', size=11, weight='bold'),
            foreground=self.text_color,
            spacing1=5,
            spacing3=3
        )
        self.display_text.tag_configure(
            'content',
            font=self.chinese_font,
            spacing1=3
        )
        print(response_data)
        # 显示历史背景
        if response_data and isinstance(response_data, dict):
            self.display_text.insert(tk.END, '历史背景\n', 'title')
            self.display_text.insert(tk.END, f'{response_data.get("history", "")}\n\n', 'content')
            
            # 显示角色信息
            self.display_text.insert(tk.END, '角色信息\n', 'title')
            characters = response_data.get('data', [])
            if isinstance(characters, list):
                for character in characters:
                    if isinstance(character, dict):
                        self.display_text.insert(tk.END, f'【{character.get("name", "")}】\n', 'subtitle')
                        for key, value in character.items():
                            if key != 'name':
                                # 将英文标签替换为中文标签
                                label = {
                                    'age': '年龄',
                                    'background': '背景',
                                    'features': '特点',
                                    'job': '职业',
                                    'sex': '性别',
                                    'skills': '技能'
                                }.get(key, key)
                                self.display_text.insert(tk.END, f'{label}: {value}\n', 'content')
                        self.display_text.insert(tk.END, '\n')
        else:
            self.display_text.insert(tk.END, '获取数据失败\n', 'title')
            self.display_text.insert(tk.END, '服务器返回的数据格式不正确\n', 'content')
        
        # 禁用文本框编辑
        self.display_text.configure(state='disabled')
        
        # 滚动到顶部
        self.display_text.see('1.0')
    
    def show_error(self, message):
        # 在显示区域显示错误信息
        self.display_text.configure(state='normal')
        self.display_text.delete('1.0', tk.END)
        self.display_text.insert(tk.END, f'错误: {message}', 'error')
        self.display_text.tag_configure(
            'error',
            foreground='red',
            font=self.chinese_font
        )
        self.display_text.configure(state='disabled')

    def expand_all(self, tree):
        """展开树形结构的所有节点"""
        def expand_node(node):
            tree.item(node, open=True)
            for child in tree.get_children(node):
                expand_node(child)
        
        for item in tree.get_children():
            expand_node(item)
    
    def collapse_all(self, tree):
        """收起树形结构的所有节点"""
        def collapse_node(node):
            tree.item(node, open=False)
            for child in tree.get_children(node):
                collapse_node(child)
        
        for item in tree.get_children():
            collapse_node(item)

if __name__ == '__main__':
    root = tk.Tk()
    app = HistoryChat(root)
    root.mainloop()